package graphics;

import geography.Location;

import java.awt.image.BufferedImage;

import structure.MazeNode;

/**
 * The meta-class for any tile in the GUI. Individual tiles know their {@link MazeNode}, {@link TileShape} and illumination-status.
 * @author Nils Klement
 *
 */
class Tile {
	private BufferedImage backgroundLight = null;
	private BufferedImage backgroundDark = null;
	
	private boolean illuminated = false;
	private boolean uncovered = false;
	
	private TileShape shape;
	private TileSprite image;
	
	private MazeNode node;
	private Location location;
	
	Tile(MazeNode inputNode){
		if(inputNode == null){
			throw new IllegalArgumentException("Node is missing.");
		}
		node = inputNode;
		
		location = node.getLocation();
		
		//determines the possible paths from this tile
		boolean up = false, down = false, left = false, right = false;
		if(node.getNorth() != null){
			up = true;
		}
		if(node.getSouth() != null){
			down = true;
		}
		if(node.getEast() != null){
			right = true;
		}
		if(node.getWest() != null){
			left = true;
		}
		
		//the tile's shape is set
		shape = TileShape.getType(up, down, left, right);
		image = new TileSprite(shape);
		
		//the bright and dark variants of this tile are set
		backgroundLight = image.getLight();
		backgroundDark = image.getDark();
	}
	
	/**
	 * Returns the {@link MazeNode} of this tile.
	 * @return {@link MazeNode}
	 */
	MazeNode getNode(){
		return node;
	}
	
	/**
	 * Switches the tile to bright.
	 */
	void lighten(){
		illuminated = true;
	}
	/**
	 * Switches the tile to dark.
	 */
	void darken(){
		illuminated = false;
	}
	
	/**
	 * Returns the {@link BufferedImage} object of this tile, depending on its current illumination.
	 * @return {@link BufferedImage}, either bright or dark.
	 */
	BufferedImage getImage(){
		if(!uncovered){
			return TileSprite.loadObject(TileObject.BLANK, true);
		}
		if(illuminated){
			return backgroundLight;
		}
		return backgroundDark;
	}
	
	boolean isIlluminated(){
		return illuminated;
	}
	
	boolean isUncovered(){
		return uncovered;
	}
	
	/**
	 * Returns the {@link TileShape} of this {@link Tile}.
	 * @return {@link TileShape} describing this {@link Tile}.
	 */
	TileShape getShape(){
		return shape;
	}
	
	/**
	 * Returns the {@link Location} of the tile bordering to the north, if it is connected, or null.
	 * @return {@link Location}
	 */
	Location getNorth(){
		if(node.getNorth() != null){
			return node.getNorth().getLocation();
		}
		return null;
	}
	/**
	 * Returns the {@link Location} of the tile bordering to the south, if it is connected, or null.
	 * @return {@link Location}
	 */
	Location getSouth(){
		if(node.getSouth() != null){
			return node.getSouth().getLocation();
		}
		return null;
	}
	/**
	 * Returns the {@link Location} of the tile bordering to the east, if it is connected, or null.
	 * @return {@link Location}
	 */
	Location getEast(){
		if(node.getEast() != null){
			return node.getEast().getLocation();
		}
		return null;
	}
	/**
	 * Returns the {@link Location} of the tile bordering to the west, if it is connected, or null.
	 * @return {@link Location}
	 */
	Location getWest(){
		if(node.getWest() != null){
			return node.getWest().getLocation();
		}
		return null;
	}
	
	/**
	 * Makes a tile visible, instead of showing black.
	 */
	void uncover(){
		uncovered = true;
	}
	
	void shroud(){
		uncovered = false;
	}
		
	Location getLocation(){
		return location;
	}
}
